home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / human interface toolbox / fragment tool / menusstuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  12.5 KB  |  594 lines

  1. /*
  2.     File:        MenusStuff.c
  3.  
  4.     Contains:    Handles the application's menus
  5.  
  6.     Written by: Chris White    
  7.  
  8.     Copyright:    Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 8/5/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23.  
  24. #include <Menus.h>
  25. #include <Windows.h>
  26. #include <Dialogs.h>
  27. #include <TextUtils.h>
  28. #include <Devices.h>
  29. #include <CodeFragments.h>
  30.  
  31.  
  32. #ifndef __MENUSTUFF__
  33.     #include "MenuStuff.h"
  34. #endif
  35.  
  36. #include "DialogStuff.h"
  37.  
  38. #ifndef __STREAMS__
  39.     #include "Streams.h"
  40. #endif
  41.  
  42. #ifndef __UTILITIES__
  43.     #include "Utilities.h"
  44. #endif
  45.  
  46. #ifndef __PROTOTYPES__
  47.     #include "Prototypes.h"
  48. #endif
  49.  
  50.  
  51.  
  52.  
  53.  
  54. static Boolean EnableFileCommands ( WindowRef frontWindow );
  55. static Boolean EnableEditCommands ( WindowRef frontWindow );
  56. static Boolean EnableFragmentCommands ( WindowRef frontWindow );
  57. static void SetItemEnable ( MenuHandle theMenu, int16 theItem, Boolean bEnabled );
  58. static void DoAppleCmds ( int16 theItem );
  59. static void DoFileCmds ( int16 theItem );
  60. static void DoFragmentCmds ( int16 theItem );
  61. static void DoGetInfo ( WindowRef theWindow );
  62. static void DoDisplayExports ( WindowRef theWindow );
  63. static void DoMoveFragments ( WindowRef theWindow );
  64. static void DoCopyFragments ( WindowRef theWindow );
  65. static void DoRemoveFragments ( WindowRef theWindow );
  66. static OSErr PackageWindowData ( WindowRef theWindow, Ptr* theData );
  67.  
  68.  
  69.  
  70.  
  71. void MenuDispatch ( int32 menuResult )
  72. {
  73.     int16     theMenu = (menuResult >> 16);                    // menu selected
  74.     int16     theItem = (menuResult & 0x0000FFFF);               // item selected
  75.     
  76.     switch (theMenu)
  77.     {
  78.         case kAppleMenu: 
  79.             DoAppleCmds ( theItem );
  80.         break;
  81.         
  82.         case kFileMenu: 
  83.             DoFileCmds ( theItem );
  84.         break;
  85.         
  86.         case kEditMenu: 
  87.             SystemEdit ( theItem - 1 );
  88.         break;
  89.         
  90.         case kFragmentMenu:
  91.             DoFragmentCmds ( theItem );
  92.         break;
  93.     }
  94.     
  95.     HiliteMenu ( 0 );               // un-hilite selected menu
  96.     
  97.     return;
  98.     
  99. } // MenuDispatch
  100.  
  101.  
  102.  
  103. void AdjustMenus ( void )
  104. {
  105.     Boolean        bRedraw = false;
  106.     WindowRef    frontWindow;
  107.     
  108.     frontWindow = FrontWindow ( );
  109.     if ( EnableFileCommands ( frontWindow ) )
  110.         bRedraw = true;
  111.     if ( EnableEditCommands ( frontWindow ) )
  112.         bRedraw = true;
  113.     if ( EnableFragmentCommands ( frontWindow ) )
  114.         bRedraw = true;
  115.     
  116.     if ( bRedraw )
  117.         DrawMenuBar ( );
  118.     
  119.     return;
  120.     
  121. } // AdjustMenus
  122.  
  123.  
  124.  
  125. static Boolean EnableFileCommands ( WindowRef frontWindow )
  126. {
  127.     static Boolean    bIsEnabled = true;
  128.     Boolean            bHasDialog = false;
  129.     Boolean            bUpdate = false;
  130.     MenuHandle    theMenu = GetMenuHandle ( kFileMenu );
  131.     
  132.     
  133.     bHasDialog = frontWindow && GetWindowKind ( frontWindow ) == dialogKind;
  134.     
  135.     if ( bIsEnabled == bHasDialog )        // Or bIsEnabled != !bHasDialog
  136.     {
  137.         SetItemEnable ( theMenu, 0, !bHasDialog );
  138.         bIsEnabled = !bHasDialog;
  139.         bUpdate = true;
  140.     }
  141.     
  142.     SetItemEnable ( theMenu, cNew, !bHasDialog );
  143.     SetItemEnable ( theMenu, cOpen, !bHasDialog );
  144.     SetItemEnable ( theMenu, cClose, frontWindow && GetWindowGoAwayFlag ( frontWindow ) );
  145.     SetItemEnable ( theMenu, cSave, frontWindow && IsDocumentDirty ( frontWindow ) );
  146.     SetItemEnable ( theMenu, cSaveAs, frontWindow  && GetWindowType ( frontWindow ) == kDocumentWindowType );
  147.     SetItemEnable ( theMenu, cQuit, !bHasDialog );
  148.     
  149.     return bUpdate;
  150.     
  151. } // EnableFileCommands
  152.  
  153.  
  154.  
  155. static Boolean EnableEditCommands ( WindowRef frontWindow )
  156. {
  157.     #pragma unused(frontWindow)
  158.     static Boolean    bIsEnabled = true;
  159.     Boolean            bEnable = false;
  160.     MenuHandle        theMenu = GetMenuHandle ( kEditMenu );
  161.     
  162.     
  163.     bEnable = false;
  164.     if ( bIsEnabled != bEnable )
  165.     {
  166.         SetItemEnable ( theMenu, 0, bEnable );
  167.         bIsEnabled = bEnable;
  168.         
  169.         return true;
  170.     }
  171.     
  172.     return false;
  173.     
  174. } // EnableEditCommands
  175.  
  176.  
  177.  
  178. static Boolean EnableFragmentCommands ( WindowRef frontWindow )
  179. {
  180.     static Boolean    bIsEnabled = true;
  181.     Boolean            bHasSelection = false;
  182.     Boolean            bHasMultiSelection = false;
  183.     MenuHandle        theMenu = GetMenuHandle ( kFragmentMenu );
  184.     
  185.     
  186.     if ( frontWindow && GetWindowType ( frontWindow ) == kDocumentWindowType )
  187.     {
  188.         int16            theIndex = 0;
  189.         tWindowInfoPtr    theInfo;
  190.         
  191.         theInfo = (tWindowInfoPtr) GetWRefCon ( frontWindow );
  192.         if ( theInfo->listRef )
  193.         {
  194.             bHasSelection = GetSelection ( theInfo->listRef, &theIndex );
  195.             theIndex++;
  196.             bHasMultiSelection = GetSelection ( theInfo->listRef, &theIndex );
  197.         }
  198.     }
  199.     
  200.     if ( bIsEnabled != bHasSelection )
  201.     {
  202.         if ( bHasSelection )
  203.         {
  204.             Boolean    bHasMultiWindows;
  205.             
  206.             
  207.             // Always better to assign true or false so that if it's checked
  208.             // against the constants, it'll still work. If we simply cast the
  209.             // result of GetNextWindow to a boolean, a true value may not be
  210.             // exactly 1. If we then use “if ( bHasMultiWindows == true )”
  211.             // the evaluation will not be what we wanted. Further, because
  212.             // only 1 byte is assigned to the boolean, we could miss all the
  213.             // important bytes (those non-zero ones) so that bHasMultiWindows
  214.             // turned out to be false.
  215.             
  216.             bHasMultiWindows = (GetNextWindow ( frontWindow )) ? true : false;
  217.             
  218.             SetItemEnable ( theMenu, 0, true );
  219.             SetItemEnable ( theMenu, cGetInfo, !bHasMultiSelection );
  220.             SetItemEnable ( theMenu, cExports, !bHasMultiSelection );
  221.             SetItemEnable ( theMenu, cMoveTo, bHasMultiWindows );
  222.             SetItemEnable ( theMenu, cCopyTo, bHasMultiWindows );
  223.             SetItemEnable ( theMenu, cRemove, true );
  224.         }
  225.         else
  226.             SetItemEnable ( theMenu, 0, false );
  227.             
  228.         bIsEnabled = bHasSelection;
  229.         
  230.         return true;
  231.     }
  232.     
  233.     return false;
  234.     
  235. } // EnableFragmentCommands
  236.  
  237.  
  238.  
  239. static void SetItemEnable ( MenuHandle theMenu, int16 theItem, Boolean bEnabled )
  240. {
  241.     if ( theMenu )
  242.     {
  243.         if ( bEnabled )
  244.             EnableItem ( theMenu, theItem );
  245.         else
  246.             DisableItem ( theMenu, theItem );
  247.     }
  248.         
  249.     return;
  250.     
  251. } // SetItemEnable
  252.  
  253.  
  254.  
  255. static void DoAppleCmds ( int16 theItem )
  256. {
  257.     Str255    name;            // string for DA name
  258.     
  259.     
  260.     switch ( theItem )
  261.     {
  262.         case cAbout:
  263.             Alert ( kAboutDialog, nil );
  264.         break;
  265.         
  266.         default:
  267.             GetMenuItemText ( GetMenuHandle ( kAppleMenu ), theItem, (StringPtr) &name );
  268.             OpenDeskAcc( (StringPtr) &name );
  269.         break;
  270.     }
  271. }
  272.  
  273.  
  274.  
  275. static void DoFileCmds ( int16 theItem )
  276. {    
  277.     switch ( theItem )
  278.     {
  279.         case cNew:
  280.             DoNewDocument ( );
  281.         break;
  282.         
  283.         case cOpen:
  284.             DoOpenDocument ( );
  285.         break;
  286.         
  287.         case cClose:
  288.             DoCloseDocument ( FrontWindow ( ) );
  289.         break;
  290.         
  291.         case cSave:
  292.             DoSave ( FrontWindow ( ) );
  293.         break;
  294.         
  295.         case cSaveAs:
  296.             DoSaveAs ( FrontWindow ( ) );
  297.         break;
  298.         
  299.         case cQuit:
  300.                                                 // Tell the application immediatly. It
  301.             gQuit = true;                        // might need to know.
  302.                                                 
  303.             if ( DoCloseAllDocuments ( ) )        // Did the user cancel?
  304.                 gQuit = false;
  305.         break;
  306.     }
  307.     
  308.     return;
  309.     
  310. } // DoFileCmds
  311.  
  312.  
  313.  
  314. static void DoFragmentCmds ( int16 theItem )
  315. {
  316.     WindowRef frontWindow = FrontWindow ( );
  317.     
  318.     switch ( theItem )
  319.     {
  320.         case cGetInfo:
  321.             DoGetInfo ( frontWindow );
  322.         break;
  323.         
  324.         case cExports:
  325.             DoDisplayExports ( frontWindow );
  326.         break;
  327.         
  328.         case cMoveTo:
  329.             DoMoveFragments ( frontWindow );
  330.         break;
  331.         
  332.         case cCopyTo:
  333.             DoCopyFragments ( frontWindow );
  334.         break;
  335.         
  336.         case cRemove:
  337.             DoRemoveFragments ( frontWindow );
  338.         break;
  339.     }
  340.     
  341.     return;
  342.     
  343. } // DoFragmentCmds
  344.  
  345.  
  346.  
  347. static void DoGetInfo ( WindowRef theWindow )
  348. {
  349.     int16        theIndex = 0;
  350.     ListRef        theList;
  351.     
  352.     theList = GetWListRef ( theWindow );
  353.     if ( GetSelection ( theList, &theIndex ) )
  354.     {
  355.         OSErr                    theErr;
  356.         DialogRef                theDialog;
  357.         tItemPtr                theItem;
  358.         Str255                    theTitle;
  359.         
  360.         
  361.         theItem = GetNthWindowItem ( theWindow, theIndex );
  362.         
  363.         GetIndString ( theTitle, 1000, 5 );
  364.         ConcatPStr ( theTitle, theItem->name, sizeof ( Str255 ) );
  365.         
  366.         theErr = CreateInfoDialog ( &theDialog, theTitle, theWindow, theIndex );
  367.         if ( theErr )
  368.             AlertUser ( kGenericErrorStr, theErr, nil );
  369.     }
  370.     
  371.     
  372.     return;
  373. }
  374.  
  375.  
  376.  
  377. static void DoDisplayExports ( WindowRef theWindow )
  378. {
  379.     int16        theIndex = 0;
  380.     ListRef        theList;
  381.     
  382.     theList = GetWListRef ( theWindow );
  383.     if ( GetSelection ( theList, &theIndex ) )
  384.     {
  385.         OSErr                    theErr;
  386.         DialogRef                theDialog;
  387.         tItemPtr                theItem;
  388.         Str255                    theTitle;
  389.         tWindowInfoPtr            theInfo;
  390.         tAddFragmentExportsRec    theRec;
  391.         
  392.         
  393.         theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
  394.         theItem = GetNthWindowItem ( theWindow, theIndex );
  395.         
  396.         GetIndString ( theTitle, 1000, 1 );
  397.         ConcatPStr ( theTitle, theItem->name, sizeof ( Str255 ) );
  398.         
  399.         theRec.bIn = false;
  400.         theRec.u.out.theSpecPtr = &theInfo->fileSpec;
  401.         theRec.u.out.theItem = theItem;
  402.         theErr = CreateListDialog ( &theDialog, kListDialogOkay, theTitle,
  403.                                     &AddFragmentExports, (void*) &theRec );
  404.         if ( theErr )
  405.         {
  406.             // If an error occured, the record may contain some useful information
  407.             
  408.             StringPtr    theString = nil;
  409.             
  410.             if ( theRec.bIn )
  411.                 theString = theRec.u.in.theErrorStr;
  412.             if ( theErr == cfragNoLibraryErr )
  413.                 AlertUser ( kUnresolvedDependenciesStr, 0, theString );
  414.             else
  415.                 AlertUser ( kGenericErrorStr, theErr, nil );
  416.         }
  417.     }
  418.     
  419.     
  420.     return;
  421. }
  422.  
  423.  
  424.  
  425. static void DoMoveFragments ( WindowRef theWindow )
  426. {
  427.     OSErr            theErr;
  428.     DialogRef        theDialog;
  429.     tDialogInfo*    theInfo;
  430.     Ptr                theData;
  431.     Str255            theTitle, windowTitle;
  432.     
  433.     
  434.     GetWTitle ( theWindow, windowTitle );
  435.     GetIndString ( theTitle, 1000, 2 );
  436.     ConcatPStr ( theTitle, windowTitle, sizeof ( Str255 ) );
  437.     
  438.     theErr = CreateListDialog ( &theDialog, kListDialogOkayCancel, theTitle,
  439.                                 &AddDocuments, nil );
  440.     if ( theErr )
  441.     {
  442.         AlertUser ( kGenericErrorStr, theErr, nil );
  443.         return;
  444.     }
  445.     
  446.     SetWindowSubType ( theDialog, kMoveFragmentWindowSubType );
  447.     
  448.     
  449.     // Packages up the window reference and an array of index
  450.     // values (precceded by an element count).
  451.     theErr = PackageWindowData ( theWindow, &theData );
  452.     if ( theErr )
  453.     {
  454.         AlertUser ( kGenericErrorStr, theErr, nil );
  455.         return;
  456.     }
  457.     
  458.     theInfo = (tDialogInfo*) GetWRefCon ( theDialog );
  459.     theInfo->refCon = (int32) theData;
  460.     
  461.     return;
  462.     
  463. }
  464.  
  465.  
  466.  
  467. static void DoCopyFragments ( WindowRef theWindow )
  468. {    
  469.     OSErr            theErr;
  470.     DialogRef        theDialog;
  471.     tDialogInfo*    theInfo;
  472.     Ptr                theData;
  473.     Str255            theTitle, windowTitle;
  474.     
  475.     
  476.     
  477.     GetWTitle ( theWindow, windowTitle );
  478.     GetIndString ( theTitle, 1000, 3 );
  479.     ConcatPStr ( theTitle, windowTitle, sizeof ( Str255 ) );
  480.     
  481.     theErr = CreateListDialog ( &theDialog, kListDialogOkayCancel, theTitle,
  482.                                 &AddDocuments, nil );
  483.     if ( theErr )
  484.     {
  485.         AlertUser ( kGenericErrorStr, theErr, nil );
  486.         return;
  487.     }
  488.     
  489.     SetWindowSubType ( theDialog, kCopyFragmentWindowSubType );
  490.     
  491.     
  492.     // Packages up the window reference and an array of index
  493.     // values (precceded by an element count).
  494.     theErr = PackageWindowData ( theWindow, &theData );
  495.     if ( theErr )
  496.     {
  497.         AlertUser ( kGenericErrorStr, theErr, nil );
  498.         return;
  499.     }
  500.     
  501.     theInfo = (tDialogInfo*) GetWRefCon ( theDialog );
  502.     theInfo->refCon = (int32) theData;
  503.     
  504.     return;
  505.     
  506. }
  507.  
  508.  
  509.  
  510. static void DoRemoveFragments ( WindowRef theWindow )
  511. {
  512.     int16        theIndex = 0;
  513.     ListRef        theList;
  514.     
  515.     theList = GetWListRef ( theWindow );
  516.     while ( GetSelection ( theList, &theIndex ) )
  517.     {
  518.         DeleteWindowFragment ( theWindow, theIndex );
  519.         theIndex++;
  520.     }
  521.     
  522.     return;
  523. }
  524.  
  525.  
  526.  
  527. //
  528. // Our refCon field is used to encapsulate the information about
  529. // the fragments being copied. Namely, the window reference and
  530. // an array of index values (precceded by an element count). This
  531. // packages up the information using a data stream.
  532. //
  533. static OSErr PackageWindowData ( WindowRef theWindow, Ptr* theData )
  534. {
  535.     OSErr            theErr;
  536.     int16            theIndex = 0;
  537.     int                theCount = 0;
  538.     ListRef            theList;
  539.     tStreamRef        theStream;
  540.     tStreamCursor    countCursor;
  541.     
  542.     
  543.     
  544.     theErr = NewStream ( &theStream, 100 );
  545.     if ( theErr )
  546.         return theErr;
  547.     
  548.     theErr = SetStreamData ( theStream, (Ptr) &theWindow, sizeof ( WindowRef ) );
  549.     if ( theErr )
  550.     {
  551.         DisposeStream ( theStream );
  552.         return theErr;
  553.     }
  554.     countCursor = GetStreamCursor ( theStream );
  555.     theErr = SetStreamData ( theStream, nil, sizeof ( int ) );
  556.     if ( theErr )
  557.     {
  558.         DisposeStream ( theStream );
  559.         return theErr;
  560.     }
  561.     
  562.     theList = GetWListRef ( theWindow );
  563.     while ( GetSelection ( theList, &theIndex ) )
  564.     {
  565.         SetStreamData ( theStream, (Ptr) &theIndex, sizeof ( int16 ) );
  566.         theCount++;
  567.         theIndex++;
  568.     }
  569.     
  570.     theErr = SetStreamCursor ( theStream, countCursor );
  571.     if ( theErr )
  572.     {
  573.         DisposeStream ( theStream );
  574.         return theErr;
  575.     }
  576.     theErr = SetStreamData ( theStream, (Ptr) &theCount, sizeof ( int ) );
  577.     if ( theErr )
  578.     {
  579.         DisposeStream ( theStream );
  580.         return theErr;
  581.     }
  582.     theErr = CompactStream ( theStream );
  583.     if ( theErr )
  584.         return theErr;
  585.     
  586.     *theData = (Ptr) theStream;
  587.     
  588.     return noErr;
  589.     
  590. } // PackageWindowData
  591.  
  592.  
  593.  
  594.